package com.yerbamateprimer.round.state.exit;

import java.util.Collection;
import java.util.List;
import java.util.Map;

import com.yerbamateprimer.action.system.SystemAction;
import com.yerbamateprimer.round.Round;
import com.yerbamateprimer.round.state.StateName;

/**
 * This interface defines 
 * a possible exit of a 
 * state.
 * 
 * @author Matias Liwski
 * @version 1.0
 */
public interface StateExit {
	/**
	 * @return The cause of this exit.
	 */
	StateExitCause getCause();

	/**
	 * Add an "immediate execution" system action.
	 * 
	 * @param action A system action to add.
	 */
	void addAction(SystemAction action);

	/**
	 * Add a "delayed" system action.
	 * 
	 * @param action A system action to add.
	 * @param delay The delay to wait before execute the action.
	 */
	void addAction(SystemAction action, Long delay);

	/**
	 * @param delay The delay to get the actions. 
	 * @return The list of actions for the provided delay.
	 */
	List<SystemAction> getActions(Long delay);

	/**
	 * @return The get out system actions with they delays.
	 */
	Map<Long, Collection<SystemAction>> getActions();

	/**
	 * @return The name of the next state to get into. 
	 */
	StateName getNextStateName();

	/**
	 * Set the state to get into.
	 * 
	 * @param nextStateName The name of next state for this state.
	 */
	void setNextStateName(StateName nextStateName);

	/**
	 * Apply this exit. This involves the following steps:
	 * <ul>
	 * 		<li>Execute each action in his delay.</li>
	 * 		<li>Get into the next state.</li>
	 * </ul>
	 * 
	 * @param round The round where the exit system actions will be applied.
	 */
	void apply(Round round);
	
	/**
	 * @param round The round to evaluate the information.
	 * @return true if this is the exit of the current state from the provided round.
	 */
	boolean isThisExit(Round round);
}